package com.taxigang.server;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gson.Gson;

public class WelcomeServlet extends HttpServlet {
	/**
	 * 
	 */

	private static final String SIGN_ALGORITHM = "HMACSHA256";

	private static final long serialVersionUID = 1L;
	private static final String UP = "../";

	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
	throws IOException {
		FacebookRequest fr = null;
		
		String mode = req.getParameter("mode");
		Log.info("url:"+mode);
		String parameterString = "?mode="+mode+"&";
		Object signed_request = req.getParameterMap().get("signed_request");
		if (signed_request != null && signed_request instanceof String[]){
			Log.info("dumping signed_request");
			String[]signed_requestList = (String[])signed_request;
			String signedRequest = signed_requestList[0];
			Log.info("signed_request:"+signedRequest);
			if (signedRequest != null){
				try {
					fr = getFacebookRequest(signedRequest);
					Log.info("liked:"+fr.getLiked());
					Log.info("pageId:"+fr.getPageId());
					Log.info("locale:"+fr.getLocale());
					parameterString+="page="+fr.getPageId()+"&";
					parameterString+="liked="+fr.getLiked()+"&";
					parameterString+="locale="+fr.getLocale();
				} catch (SocialNetworkingException e) {
					Log.error(e.getMessage());
				}
			}
		}


		String prefix = "";

		if (req.getRequestURL().indexOf("welcometaxigang") >=0){
			prefix = UP;
		}
		String redirect = prefix+parameterString;
		Log.info("redirect:"+redirect);
		resp.sendRedirect(redirect);

	}

	private static final String secret = "136cdc4e7866c592fb78351da0947cae";

	private FacebookRequest getFacebookRequest(String sigreq) throws SocialNetworkingException{

		/* split the string into signature and payload */ 
		int idx = sigreq.indexOf(".");
		byte[] sig = new Base64(true).decode(sigreq.substring(0, idx).getBytes());
		String rawpayload = sigreq.substring(idx+1);
		String payload = new String(new Base64(true).decode(rawpayload));

		/* parse the JSON payload and do the signature check */
		FacebookRequest ret = new Gson().fromJson(payload, FacebookRequest.class); 
		/* check if it is HMAC-SHA256 */
//		if (!ret.getAlgorithm().equals("HMAC-SHA256")) {
//			/* note that this follows facebooks example, as published on 2010-07-21 (I wonder when this will break) */
//			throw new SocialNetworkingException("Unexpected hash algorithm " + ret.getAlgorithm());
//		}
		/* then check the signature */
		//checkSignature(rawpayload, sig);
		return ret;
	}


	private void checkSignature(String rawpayload, byte[] sig) throws SocialNetworkingException{
		try {
			SecretKeySpec secretKeySpec = new SecretKeySpec(secret.getBytes(), SIGN_ALGORITHM);
			Mac mac = Mac.getInstance(SIGN_ALGORITHM);
			mac.init(secretKeySpec);
			byte[] mysig = mac.doFinal(rawpayload.getBytes());
			if (!Arrays.equals(mysig, sig)) {
				throw new SocialNetworkingException("Non-matching signature for request");
			}
		} catch (NoSuchAlgorithmException e) {
			throw new SocialNetworkingException("Unknown hash algorithm " + SIGN_ALGORITHM, e);
		} catch (InvalidKeyException e) {
			throw new SocialNetworkingException("Wrong key for " + SIGN_ALGORITHM, e);
		}
	}

}